﻿Imports ClaimsModel.Model
Imports ClaimsModel.Model.DBMappers

Namespace Services

    Public Class BatchPaymentService

        Private Shared eteriaAmountCalculator As New EteriaAmountCalculator
        Private Shared katepistevmaAmountCalculator As New KatepistevmaAmountCalculator

        Public Enum PaymentAppliesTo
            KATAPISTEVMA = 1
            ETERIA = 2
            BOTH = 3
        End Enum

        Private _Payment As Model.BatchPayment
        Private _ClaimsToProcess As List(Of Claim)

        Public Sub doPayment(appliesto As PaymentAppliesTo, percentage As Decimal, exeDate As DateTime)

            _Payment = BatchPaymentFactory.Create
            _Payment.AppliesTo = appliesto
            _Payment.Percentage = percentage
            _Payment.ExecuteDate = exeDate
            Try


                ModelContext.beginTrans()
                'call save to get primary key
                Call BatchPaymentDataUtils.saveBatchPayment(_Payment)

                Me.applyAmounts()

                Call ClaimDataUtils.saveClaim(Me.ClaimsToProcess.ToArray)
                ModelContext.commitTrans()
            Finally
                ModelContext.rollbackTrans()
            End Try
        End Sub

        Public ReadOnly Property AppliesTo() As PaymentAppliesTo
            Get
                Return CType(_Payment.AppliesTo, PaymentAppliesTo)
            End Get
        End Property

        Public ReadOnly Property ClaimsToProcess() As List(Of Claim)
            Get
                Dim where As String
                If _ClaimsToProcess Is Nothing Then
                    If Me._Payment.AppliesTo = PaymentAppliesTo.KATAPISTEVMA Then
                        where = "EPAL_EXIST = 'Ν' -- Filter is in GREEK (""N""AI --> YES)"
                        where = where & vbCrLf & " AND EPAL_ACC_KAT > 0"
                    ElseIf Me._Payment.AppliesTo = PaymentAppliesTo.ETERIA Then
                        where = "EPAL_EXIST = 'Ν' -- Filter is in GREEK (""N""AI --> YES)"
                        where = where & vbCrLf & "AND EPAL_ACC_CO > 0"
                    ElseIf Me._Payment.AppliesTo = PaymentAppliesTo.BOTH Then
                        where = "EPAL_EXIST = 'Ν' -- Filter is in GREEK (""N""AI --> YES)"
                        where = where & vbCrLf & "AND (EPAL_ACC_CO > 0 or  EPAL_ACC_KAT > 0)"
                    Else
                        Throw New ApplicationException("Illegal Applies to")
                    End If

                    _ClaimsToProcess = ClaimDataUtils.findList(where)

                End If
                Return _ClaimsToProcess
            End Get
        End Property
        Public ReadOnly Property Percentage() As Decimal
            Get
                Return Me._Payment.Percentage.GetValueOrDefault
            End Get
        End Property

        Private Sub applyAmounts()

            Dim claimsList As List(Of Claim) = Me.ClaimsToProcess

            For Each cl As Claim In claimsList
                If Me.AppliesTo = PaymentAppliesTo.BOTH Then
                    ' -- ===================================================================================
                    '-- Check if the @katAmountAccepted / @coAmountAccepted is greater than zero.
                    '-- ONLY If YES, apply the same logic as in the @AppliesTo = 1 / @AppliesTo = 2 section
                    '-- ===================================================================================
                    If cl.EpalAccKat > 0.0 Then
                        Me.getAmountCalculator(PaymentAppliesTo.KATAPISTEVMA).applyAmount(cl, Me.Percentage)
                    End If
                    If cl.EpalAccCo > 0.0 Then
                        Me.getAmountCalculator(PaymentAppliesTo.ETERIA).applyAmount(cl, Me.Percentage)
                    End If

                Else
                    Me.getAmountCalculator(Me.AppliesTo).applyAmount(cl, Me.Percentage)

                End If
                If cl.isDirty Then
                    'recalculate all amounts!
                    cl.calculateAndsetAmounts()

                    Dim claimPayment As Model.PaymentClaim = Model.PaymentClaimFactory.Create
                    claimPayment.PaymentId = Me._Payment.PaymentId
                    cl.AddPayment(claimPayment)

                End If
            Next
        End Sub

        Private Function getAmountCalculator(pmntAppliesTo As PaymentAppliesTo) As IAmountCalculator

            If pmntAppliesTo = PaymentAppliesTo.ETERIA Then
                Return eteriaAmountCalculator

            ElseIf pmntAppliesTo = PaymentAppliesTo.KATAPISTEVMA Then
                Return katepistevmaAmountCalculator

            Else
                Throw New ApplicationException("getAmountCalculator expects PaymentAppliesTo.ETERIA or PaymentAppliesTo.KATAPISTEVMA")
            End If

        End Function

    End Class
End Namespace